package cmd

import (
	"fmt"
	"sort"

	"github.com/gookit/color"
	"starsine.cn/appTpl/cmn/config/aconf"
	"starsine.cn/appTpl/cmn/config/hconf"
	"starsine.cn/appTpl/cmn/gcli/v3"
	peerclient "starsine.cn/appTpl/svcapp/peers/client"
	svcclientmng "starsine.cn/appTpl/svcpeers/client"
	"starsine.cn/appTpl/svcregistry/grpc/handler"
)

// ///////// "github.com/gookit/gcli/v3"
var gCliApp *gcli.App = nil

func GCliStart() *gcli.App {
	gCliApp = gcli.NewApp()
	gCliApp.Version = "1.0.0"
	gCliApp.Desc = "appTpl app commands."

	gCliApp.Add(Help)
	gCliApp.Add(TestGRpc)
	gCliApp.Add(DumpConfig)
	gCliApp.Add(DumpSvcInfo)
	gCliApp.Add(DumpSvcDepStatus)
	gCliApp.Add(DumpSvcClientMng)

	return gCliApp
}

var Help = &gcli.Command{
	Func:    helpExecute,
	Name:    "help",
	Aliases: []string{"h", "hlp"},
	Desc:    "show command list and command summary.",
	Examples: `
	help
`,
	Config: func(c *gcli.Command) {
		c.AddArg("arg0", "command name", false)
	},
}

func helpExecute(c *gcli.Command, args []string) (string, error) {
	info := ""
	magentaln := color.Magenta.Println
	color.Infoln("HELP")

	arr := c.Arg("arg0")
	if arr.Value.String() != "" {
		gCliApp.ShowCommandHelp(arr.Value.String())
		c.Arg("arg0").SetValue("")
		return "", nil
	}

	color.Cyanln("All Commands:")
	cmdList := []string{}
	for k, v := range gCliApp.Commands() {
		cmdList = append(cmdList, fmt.Sprintf("%-20s: %s %s", k, v.Aliases, v.Desc))
	}
	sort.Slice(cmdList, func(i, j int) bool {
		return cmdList[i] < cmdList[j]
	})
	for c, cmdstr := range cmdList {
		info += fmt.Sprintf("(%-2d) %s\n", c, cmdstr)
	}

	magentaln(info)
	return info, nil
}

var TestGRpc = &gcli.Command{
	Func:    execTestGRpc,
	Name:    "testgrpc",
	Aliases: []string{"tgrpc"},
	Desc:    "test grpc api",
	Examples: `
	testgrpc
	tgrpc
`,
	Config: func(c *gcli.Command) {
	},
}

func execTestGRpc(c *gcli.Command, args []string) (string, error) {
	color.Infoln("%s --->", c.Name)

	in := "svc log test write json stream"
	peerclient.SvcLogWrite([]byte(in))

	color.Cyanf("grpc peerclient.SvcLogWrite(%s) ok\n", in)

	return "execTestGRpc ok", nil
}

var DumpConfig = &gcli.Command{
	Func:    execDumpConfig,
	Name:    "dumpconfig",
	Aliases: []string{"dpcfg"},
	Desc:    "dump all config information",
	Examples: `
	dumpconfig
	dpcfg
`,
	Config: func(c *gcli.Command) {
	},
}

func execDumpConfig(c *gcli.Command, args []string) (string, error) {
	color.Infoln("dumpconfig --->")
	magentaln := color.Magenta.Println

	out := ""
	out += hconf.DumpConfig()
	conf := aconf.DumpConfigs()
	for k, v := range conf {
		out += fmt.Sprintf("%s:%v\n", k, v)
	}

	magentaln(out)

	return out, nil
}

var DumpSvcInfo = &gcli.Command{
	Func:    execDumpSvcInfo,
	Name:    "dumpsvcinfo",
	Aliases: []string{"svcinfo"},
	Desc:    "dump service information",
	Examples: `
	dumpsvcinfo
	svcinfo
`,
	Config: func(c *gcli.Command) {
	},
}

func execDumpSvcInfo(c *gcli.Command, args []string) (string, error) {
	color.Infoln("dump service information --->")
	magentaln := color.Magenta.Println

	out := handler.GetSvcInfo()

	magentaln(out)

	return out, nil
}

var DumpSvcDepStatus = &gcli.Command{
	Func:    execDumpSvcDepStatus,
	Name:    "dumpsvcdepstatus",
	Aliases: []string{"svcdeps"},
	Desc:    "dump service information",
	Examples: `
	dumpsvcdepstatus
	svcdeps
`,
	Config: func(c *gcli.Command) {
	},
}

func execDumpSvcDepStatus(c *gcli.Command, args []string) (string, error) {
	color.Infoln("dump service dependence status --->")
	magentaln := color.Magenta.Println

	out := peerclient.DumpSvcDepStatus()

	magentaln(out)

	return out, nil
}

var DumpSvcClientMng = &gcli.Command{
	Func:    execDumpSvcClientMng,
	Name:    "dumpsvcclientmng",
	Aliases: []string{"dpcmng"},
	Desc:    "dump SvcClientMng map data",
	Examples: `
	dumpsvcclientmng
	dpcmng
`,
	Config: func(c *gcli.Command) {
	},
}

func execDumpSvcClientMng(c *gcli.Command, args []string) (string, error) {
	color.Infoln("dumpsvcclientmng --->")
	magentaln := color.Magenta.Println

	out := svcclientmng.Dump()

	magentaln(out)

	return out, nil
}
